import java.util.Comparator;
import java.util.Objects;

/**
 * Created with IntelliJ IDEA
 * Description:
 * User: lenovo
 * Date: 2023 -06 -25
 * Time: 8:58
 */
class Student /*implements Comparable<Student>*/{
    public String name;
    public int age;

   /* @Override
    *//**
     * 关于compareTo
     * 谁调用compareTo谁就是this
     * 返回值为int,即compareTo可以确切的比较出具体的大小
     */
   /* public int compareTo(Student o) {
        return this.age-o.age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;//如果是自己与自己比较,直接返回true;
        if (o == null || getClass() != o.getClass()) return false;//如果比较的对象有一个是null
        //或者是属于两个不同对象之间的比较,返回false;
        Student student = (Student) o;//如果不是以上两种情况,我们将传入的对象强转为Student
        //因为你前面是拿Object接收的
        return age == student.age && Objects.equals(name, student.name);//到这里
        //我们去比较两个对象之间的内容,如果都相等返回ture如果有一个不相等,返回false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }*/
}

/**
 * 这是年龄的比较器
 */
class AgeComparator implements Comparator<Student>{

    @Override
    public int compare(Student o1, Student o2) {
        return o1.age- o2.age;
    }
}

/**
 * 这是名字的比较器
 */
class NameComparator implements Comparator<Student>{

    @Override
    public int compare(Student o1, Student o2) {
        //注意这里name是引用类型,因此不能直接用==进行比较,而且compare的返回值是int
        //所以也不能用equals,要用compareTo来进行比较
        return o1.name.compareTo(o2.name);
    }
}
/**
 * 关于常见的三种比较方式的一个讲解
 * 1.equals
 * 2.Comparable的compareTo方法
 * 3.Comparator
 */
public class Test {
    /**
     * 这种使用Comparator的方式是比较好的
     * 1.Comparator方法可以写在Student这个类的外面,对类的侵入性较小
     * 2.我们可以在外面实现很多我们想要比较的,不同的Comparator方法
     * 这也就体现了泛型的好处
     * (泛型的特点:将类型作为参数)
     * @param args
     */
    public static void main(String[] args) {
        Student student1=new Student();
        student1.name="张三";
        student1.age=9;
        Student student2=new Student();
        student2.name="张三";
        student2.age=8;
        AgeComparator ageComparator=new AgeComparator();
        System.out.println(ageComparator.compare(student1, student2));
        NameComparator nameComparator=new NameComparator();
        System.out.println(nameComparator.compare(student1, student2));
    }
    /**
     * 使用compareTo确实可以具体的比较出大小,但是对于Student这个类而言不是那么友好
     * 毕竟一个compareTo只能比较一种数据,假设我们现在不用age来比较了,我们要用名字去进行比较
     * 那么我们就要再次写一个compareTo方法,用名字比较和用年龄比较的思路是一样的
     * 而且假设我们要用到很多的不同的比较方式,那么我们就要在Student这个类里面写很多的compareTo方法
     * 当一个类当中为了实现一个功能而去写了很多重复的代码,那么我们就称,这种方法对类的侵入性大
     * 也就是说,在这里compareTo对类的侵入性大
     * @param args
     */
    public static void main3(String[] args) {
        Student student1=new Student();
        student1.name="张三";
        student1.age=9;
        Student student2=new Student();
        student2.name="张三";
        student2.age=8;
        //我们在上面Student这个类当中实现了Comparable这个接口,并且重写了compareTo这个方法
        //上面实现的是对年龄的比较,所以在这里打印出的结果是1
       //System.out.println(student1.compareTo(student2));

    }
    /**
     * 请注意,equals这个方法只能比较出是否相等
     * 即它的返回值是Boolean类型的,无法比较具体的大小
     * @param args
     */
    public static void main2(String[] args) {
        Student student1=new Student();
        student1.name="张三";
        Student student2=new Student();
        student2.name="张三";
        //由main1可知,main1的方法不可取
        // 那么我们该如何跳过比较引用所指向的对象的地址
        //直接来比较这两个引用所指向对象的内容呢?
        //1.重写equals方法
        System.out.println(student1.name.equals(student2.name));
    }
    public static void main1(String[] args) {
        Student student1=new Student();
        student1.name="张三";
        Student student2=new Student();
        student2.name="张三";
        System.out.println(student1 == student2);
        //这种情况下肯定结果是false,因为student1与student2这两个引用所指向的是两个不同的对象
        //对象与对象之间直接用==比较实际上是比较两个引用所指向的对象
    }
}
